﻿using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using System;

namespace Niknak.Social.Common.Http
{
    /// <summary>
    /// Basic DelegatingHandler that creates an OAuth authorization header based on the OAuthBase
    /// class downloaded from http://oauth.net
    /// </summary>
    public class OAuthMessageHandler<OAuthSettings> : DelegatingHandler where OAuthSettings : IOAuthSettings, new()
    {
        private static OAuthSettings Settings
        {
            get { return new OAuthSettings(); }
        }

        private OAuthBase _oAuthBase = new OAuthBase();

        public OAuthMessageHandler(HttpMessageHandler innerHandler)
            : base(innerHandler)
        {
            if (Settings == null)
                throw new Exception("Missing Settings implementation");
            if (string.IsNullOrEmpty(Settings.ConsumerKey))
                throw new Exception("Missing ConsumerKey");
            if (string.IsNullOrEmpty(Settings.ConsumerSecret))
                throw new Exception("Missing ConsumerSecret");
            if (string.IsNullOrEmpty(Settings.Token))
                throw new Exception("Missing Token");
            if (string.IsNullOrEmpty(Settings.TokenSecret))
                throw new Exception("Missing TokenSecret");
        }

        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            // Compute OAuth header 
            string normalizedUri;
            string normalizedParameters;
            string authHeader;

            string timestamp = _oAuthBase.GenerateTimeStamp();
            string nonce = _oAuthBase.GenerateNonce();

            //debug from oauth tool
            //timestamp = "1366636898";
            //nonce = "f53860b65ea3a77592cf7bd23f0409c1";
            
            Console.WriteLine("Timestamp = " + timestamp);

            string signature = _oAuthBase.GenerateSignature(
                request.RequestUri,
                Settings.ConsumerKey,
                Settings.ConsumerSecret,
                Settings.Token,
                Settings.TokenSecret,
                request.Method.Method,
                timestamp,
                nonce,
                out normalizedUri,
                out normalizedParameters,
                out authHeader);

            Console.WriteLine("Signature = " + signature);
            Console.WriteLine("Auth header = " + authHeader);

            request.Headers.Authorization = new AuthenticationHeaderValue("OAuth", authHeader);
            return base.SendAsync(request, cancellationToken);
        }
    }
}